﻿using AutoMapper;
using Modules.Constructor;
using Modules.Corp;
using Modules.Project;
using Modules.System.Area;
using PmSoft;
using static Modules.BankSpecialAccount.BankSpecialAccountConstants;
using Modules.System.User;
using Modules.Common;
using PmSoft.ApplicationContext;
using PmSoft.Entity;
using Modules.BankSpecialAccount;

namespace ManagementApi.Models.Manage.ProjectSpecialAccount
{
    public class ProjectSpecialAccountDto : OperateDto
    {
        public int Id { get; set; }

        /// <summary>
        /// 编号
        ///</summary>
        public string Code { get; set; }

        /// <summary>
        /// 流水号
        ///</summary>
        public int SerialNumber { get; set; }

        /// <summary>
        /// 项目ID
        ///</summary>
        public int ProjectId { get; set; }

        /// <summary>
        /// 项目名称
        /// </summary>
        public string ProjectName { get; set; }

        /// <summary>
        /// 项目名称
        /// </summary>
        public string ProjectNum { get; set; }

        /// <summary>
        /// 账户名称
        ///</summary>
        public string Username { get; set; }

        /// <summary>
        /// 专户签约时间
        /// </summary>
        public DateTime AccountCreateTime { get; set; }

        /// <summary>
        /// 申请日期
        ///</summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 开户日期
        ///</summary>
        public DateTime OpenDate { get; set; }

        /// <summary>
        /// 开户银行
        ///</summary>
        public string BankType { get; set; }

        /// <summary>
        /// 银行名称
        ///</summary>
        public string? BankName { get; set; }

        /// <summary>
        /// 开户支行
        /// </summary>
        public string BankSubbranch { get; set; }

        /// <summary>
        /// 银行操作员工号
        /// </summary>
        public string OptUserCode { get; set; }

        /// <summary>
        /// 银行操作员姓名
        /// </summary>
        public string OptUserName { get; set; }

        /// <summary>
        /// 开户人
        ///</summary>
        public string? Creator { get; set; }

        /// <summary>
        /// 银行账号
        ///</summary>
        public string? BankNo { get; set; }

        /// <summary>
        /// 开户地址
        ///</summary>
        public string? BankAddress { get; set; }

        /// <summary>
        /// 银行是否对账户设置特殊标识(0否,1是)
        ///</summary>
        public bool BankMark { get; set; }

        /// <summary>
        /// 工资专户余额(元)
        ///</summary>
        public decimal? Balance { get; set; }

        /// <summary>
        /// 账户状态(1 待验证, 2 正常,3 补办,4 挂失,5 注销,6 冻结,7 其他)
        /// 默认值: 1
        ///</summary>
        public 专户状态 AccountStatus { get; set; }

        /// <summary>
        /// 账户状态
        ///</summary>
        public string? AccountStatusName { get; set; }

        /// <summary>
        /// 注销者
        /// </summary>
        public string? Canceller { get; set; }

        /// <summary>
        /// 注销理由
        /// </summary>
        public string? CancelReason { get; set; }

        /// <summary>
        /// 注销时间
        /// </summary>
        public string? CancelTime { get; set; }

        /// <summary>
        /// 建设单位名称
        /// </summary>
        public string? ConstructorName { get; set; }

        /// <summary>
        /// 建设单位审核人
        /// </summary>
        public string? ConstructorChecker { get; set; }

        /// <summary>
        /// 建设单位审核人证件类型
        /// </summary>
        public string? ConstructorType { get; set; }

        /// <summary>
        /// 建设单位审核人身份证号
        /// </summary>
        public string? ConstructorCardNo { get; set; }

        /// <summary>
        /// 建设单位手机号
        /// </summary>
        public string? ConstructorMobile { get; set; }

        /// <summary>
        /// 总承包名称
        /// </summary>
        public string? LumpContractorCorpName { get; set; }

        /// <summary>
        /// 总承包审核人证件类型
        /// </summary>
        public string? LumpContractorCorpType { get; set; }

        /// <summary>
        /// 总承包审核人身份证号
        /// </summary>
        public string? LumpContractorCorpCardNo { get; set; }

        /// <summary>
        /// 总承包审核人
        /// </summary>
        public string? LumpContractorCorpChecker { get; set; }

        /// <summary>
        /// 总承包手机号
        /// </summary>
        public string? LumpContractorCorpMobile { get; set; }

        /// <summary>
        /// 项目地址
        /// </summary>
        public string? FullAddress { get; set; }

        /**扩展字段**/

        /// <summary>
        /// 进账
        /// </summary>
        public decimal IncomeAmount { get; set; }

        /// <summary>
        /// 线上代发
        /// </summary>
        public decimal OnlinePaymentAmount { get; set; }

        /// <summary>
        /// 线下代发
        /// </summary>
        public decimal OfflinePaymentAmount { get; set; }
    }

    public class ReviewBankAccountDto
    {
        /// <summary>
        /// 编号
        ///</summary>
        public string Code { get; set; }

        /// <summary>
        /// 项目名称
        /// </summary>
        public string ProjectName { get; set; }

        /// <summary>
        /// 项目编号
        /// </summary>
        public string ProjectNum { get; set; }

        /// <summary>
        /// 账户名称
        ///</summary>
        public string Username { get; set; }

        /// <summary>
        /// 申请日期
        ///</summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 开户日期
        ///</summary>
        public DateTime OpenDate { get; set; }

        /// <summary>
        /// 专户签约时间
        /// </summary>
        public DateTime AccountCreateTime { get; set; }

        /// <summary>
        /// 开户银行
        ///</summary>
        public string BankType { get; set; }

        /// <summary>
        /// 银行名称
        ///</summary>
        public string? BankName { get; set; }

        /// <summary>
        /// 开户支行
        /// </summary>
        public string BankSubbranch { get; set; }

        /// <summary>
        /// 开户人
        ///</summary>
        public string? Creator { get; set; }

        /// <summary>
        /// 银行账号
        ///</summary>
        public string? BankNo { get; set; }

        /// <summary>
        /// 开户地址
        ///</summary>
        public string? BankAddress { get; set; }

        /// <summary>
        /// 银行是否对账户设置特殊标识(0否,1是)
        ///</summary>
        public bool BankMark { get; set; }

        /// <summary>
        /// 工资专户余额(元)
        ///</summary>
        public decimal? Balance { get; set; }

        /// <summary>
        /// 账户状态
        ///</summary>
        public string? AccountStatusName { get; set; }

        /// <summary>
        /// 注销者
        /// </summary>
        public string? Canceller { get; set; }

        /// <summary>
        /// 注销者工号
        /// </summary>
        public string? CancelNo { get; set; }

        /// <summary>
        /// 注销理由
        /// </summary>
        public string? CancelReason { get; set; }

        /// <summary>
        /// 注销时间
        /// </summary>
        public string? CancelTime { get; set; }

        /// <summary>
        /// 建设单位名称
        /// </summary>
        public string? ConstructorName { get; set; }

        /// <summary>
        /// 建设单位审核人
        /// </summary>
        public string? ConstructorChecker { get; set; }

        /// <summary>
        /// 建设单位审核人身份证号
        /// </summary>
        public string? ConstructorType { get; set; }

        /// <summary>
        /// 建设单位手机号
        /// </summary>
        public string? ConstructorMobile { get; set; }

        /// <summary>
        /// 总承包名称
        /// </summary>
        public string? LumpContractorCorpName { get; set; }

        /// <summary>
        /// 总承包审核人
        /// </summary>
        public string? LumpContractorCorpChecker { get; set; }

        /// <summary>
        /// 总承包审核人身份证号
        /// </summary>
        public string? LumpContractorCorpNo { get; set; }

        /// <summary>
        /// 总承包手机号
        /// </summary>
        public string? LumpContractorCorpMobile { get; set; }

        /// <summary>
        /// 项目地址
        /// </summary>
        public string? FullAddress { get; set; }
    }

    public static partial class ProjectSpecialAccountExceptions
    {
        public static ProjectSpecialAccountDto AsProjectSpecialAccountDto(this Modules.BankSpecialAccount.Entitys.BankSpecialAccountInfo projectSpecialAccount, IApplicationContext applicationContext)
        {
            ProjectSpecialAccountDto dto = new ProjectSpecialAccountDto();
            var projectService = applicationContext.GetService<ProjectService>();
            var constructorService = applicationContext.GetService<ConstructorService>();
            var projectSpecialAccountStatisticService = applicationContext.GetService<BankSpecialAccountStatisticService>();
            var corpService = applicationContext.GetService<CorpService>();
            var mapper = applicationContext.GetService<IMapper>();
            mapper.Map(projectSpecialAccount, dto);
            dto.AccountStatusName = projectSpecialAccount.AccountStatus.GetDescription();
            dto.Balance = dto.Balance;
            var projectInfo = projectService.GetProjectInfo(dto.ProjectId);
            if (projectInfo != null)
            {
                dto.ProjectName = projectInfo.Name;
                dto.ProjectNum = projectInfo.PrjNum;

                #region 主管单位数据权限

                if (applicationContext.CurrentUser is IDeptUser deptUser)
                {
                    if (deptUser.IsSuperAdministrator() || deptUser.IsBankAdministrator() || projectInfo.DeptId == deptUser.DeptId)
                        dto.HasEdit = true;
                    else dto.HasEdit = false;
                }

                #endregion 主管单位数据权限

                dto.ConstructorName = constructorService.GetConstructorInfo(projectInfo.BuildCorpId)?.Name;
                dto.LumpContractorCorpName = corpService.GetCorpInfo(projectInfo.LumpContractorCorpId)?.Name;
                var areaService = applicationContext.GetService<Modules.System.Area.AreaService>();
                var area = areaService.GetAreaTuple(projectInfo.AreaCode);
                dto.FullAddress = areaService.GetAreaFullName(area.ProvinceCode, area.CityCode, area.AreaCode) + projectInfo.Address;
            }

            if (dto.AccountStatus == 专户状态.正常 && dto.BankNo != null)
            {
                var statistic = projectSpecialAccountStatisticService.GetProjectSpecialAccountStatisticByBankAccount(dto.BankNo);
                if (statistic != null)
                {
                    dto.IncomeAmount = statistic.IncomeAmount;
                    dto.OnlinePaymentAmount = statistic.OnlinePaymentAmount;
                    dto.OfflinePaymentAmount = statistic.OfflinePaymentAmount;
                }
            }
            return dto;
        }

        public static ReviewBankAccountDto AsReviewBankAccountDto(this Modules.BankSpecialAccount.Entitys.BankSpecialAccountInfo projectSpecialAccount)
        {
            ReviewBankAccountDto dto = new ReviewBankAccountDto();
            var projectService = ServiceAccessor.GetService<ProjectService>();
            var constructorService = ServiceAccessor.GetService<ConstructorService>();
            var corpService = ServiceAccessor.GetService<CorpService>();
            var mapper = ServiceAccessor.GetService<IMapper>();
            mapper.Map(projectSpecialAccount, dto);
            dto.AccountStatusName = projectSpecialAccount.AccountStatus.GetDescription();
            dto.Balance = dto.Balance;
            var projectInfo = projectService.GetProjectInfo(projectSpecialAccount.ProjectId);
            if (projectInfo != null)
            {
                dto.ProjectName = projectInfo.Name;
                dto.ProjectNum = projectInfo.PrjNum;
                dto.ConstructorName = constructorService.GetConstructorInfo(projectInfo.BuildCorpId)?.Name;
                dto.LumpContractorCorpName = corpService.GetCorpInfo(projectInfo.LumpContractorCorpId)?.Name;
                var areaService = ServiceAccessor.GetService<Modules.System.Area.AreaService>();
                var area = areaService.GetAreaTuple(projectInfo.AreaCode);
                dto.FullAddress = areaService.GetAreaFullName(area.ProvinceCode, area.CityCode, area.AreaCode) + projectInfo.Address;
            }
            return dto;
        }
    }
}